// http 编程
// package main

// import (
// 	"fmt"
// 	"io/ioutil"
// 	"net/http"
// )

// func main() {
// 	client := &http.Client{}
// 	request, err := http.NewRequest("get", "http://www.baidu.com", nil)
// 	if err != nil {
// 		fmt.Println(err)
// 	}

// 	// 设置request header
// 	request.Header.Set("Connect", "keep-alive")

// 	response, err := client.Do(request)
// 	fmt.Println(response.StatusCode)
// 	// fmt.Printf("%t", response.Body) // 无法打印
// 	res, err := ioutil.ReadAll(response.Body)
// 	if err != nil {
// 		fmt.Println(err)
// 	}
// 	fmt.Println(string(res))

// }

// 使用HTTP get 方法快速发起请求
// import (
// 	"fmt"
// 	"io/ioutil"
// 	"net/http"
// )

// func main() {
// 	response, err := http.Get("https://www.baidu.com")  // 高度封装，参数少， 无法个人定制请求
// 	if err != nil {
// 		fmt.Println(err)
// 	}
// 	defer response.Body.Close()

// 	body, _ := ioutil.ReadAll(response.Body)
// 	fmt.Println(string(body))
// }

// post 请求
// import (
// 	"fmt"
// 	"io/ioutil"
// 	"net/http"
// 	"strings"
// )

// func main() {
// 	client := &http.Client{}
// 	body := ioutil.NopCloser(strings.NewReader("user=admin&pass=admin"))
// 	req, err := http.NewRequest("POST", "http://www.baidu.com", body)
// 	if err != nil {
// 		fmt.Println(err)
// 	}
// 	req_body, err := ioutil.ReadAll(req.Body)
// 	fmt.Println(string(req_body))

// 	resp, err := client.Do(req)  // do 执行时 会调用 closeBody方法
// 	if err != nil {
// 		fmt.Println(err)
// 	}

// 	req_body, err = ioutil.ReadAll(resp.Request.Body)
// 	if err != nil {
// 		fmt.Println(err)
// 	}
// 	fmt.Println(string(req_body))
// }

// post 快速方法
// package main

// import (
// 	"fmt"
// 	"io/ioutil"
// 	"net/http"
// 	"strings"
// )

// func main() {
// 	resp, err := http.Post("http://www.baidu.com",
// 		"application/x-www-form-urlencoded",
// 		strings.NewReader("user=admin&pass=admin"))
// 	if err != nil {
// 		fmt.Println(err)
// 	}

// 	defer resp.Body.Close()
// 	body, err := ioutil.ReadAll(resp.Body)
// 	if err != nil {
// 		fmt.Println(err)
// 	}
// 	fmt.Println(string(body))
// }

// 爬虫框架 gocolly
/* 特性
 */
// package main

// import (
// 	"fmt"
// 	"github.com/gocolly/colly"
// )

// func main() {
// 	c := colly.NewCollector()
// 	// 查找和访问所有的链接
// 	c.OnHTML("a[href]", func(e *colly.HTMLElement) {
// 		e.Request.Visit(e.Attr("href"))
// 	})

// 	c.OnRequest(func(r *colly.Request) {
// 		fmt.Println("Visiting", r.URL)
// 	})

// 	c.Visit("http://go-colly.org/")
// }

// 请求前设置其他参数
// package main

// import (
// 	"fmt"

// 	"github.com/gocolly/colly"
// )

// func main() {
// 	// 声明初始化NewCollector 可指定Agent 递归深度 url过滤  domain
// 	c := colly.NewCollector(
// 		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"))

// 	// 发出请求时 回调
// 	c.OnRequest(func(r *colly.Request) {
// 		r.Headers.Set("Connection", "keep-alive")
// 		r.Headers.Set("Accept", "*/*")
// 		r.Headers.Set("Origin", "")
// 		r.Headers.Set("Accept-Encoding", "gzip, deflate")
// 		r.Headers.Set("Accept-Language", "zh-CN, zh;q=0.9")
// 		fmt.Println("Visiting", r.URL)
// 	})

// 	c.OnResponse(func(r *colly.Response) {
// 		fmt.Println("response received", r.StatusCode)
// 	})

// 	c.OnHTML("title", func(e *colly.HTMLElement) {
// 		fmt.Println("title", e.Text)
// 	})

// 	c.Visit("https://www.baidu.com")

// }

// 爬取代理IP
package main

import (
	"fmt"
	"strconv"

	"strings"

	"github.com/antchfx/htmlquery"
	"github.com/gocolly/colly"
)

func main() {
	c := colly.NewCollector(
		colly.UserAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"))

	// 发出请求时 回调
	c.OnRequest(func(r *colly.Request) {

		r.Headers.Set("Connection", "keep-alive")
		r.Headers.Set("Accept", "*/*")
		r.Headers.Set("Origin", "")
		r.Headers.Set("Accept-Encoding", "gzip, deflate")
		r.Headers.Set("Accept-Language", "zh-CN, zh;q=0.9")
		fmt.Println("Visiting", r.URL)
	})

	// 打印响应状态码
	c.OnResponse(func(r *colly.Response) {
		fmt.Println("response received", r.StatusCode)
	})

	// 对响应的HTML元素处理
	c.OnHTML("title", func(e *colly.HTMLElement) {
		fmt.Println("title", e.Text)
	})

	// 在OnResponse 之后被调用
	// c.OnHTML("table", func(e *colly.HTMLElement) {
	// 	fmt.Println("check html")
	// 	// fmt.Println(e.Text)
	// 	e.ForEach("tr > td:nth-of-type(2)", func(i int, element *colly.HTMLElement) {
	// 		fmt.Println(element.Text)
	// 	})
	// })

	// 使用xpath解析
	c.OnResponse(func(r *colly.Response) {
		doc, err := htmlquery.Parse(strings.NewReader(string(r.Body)))
		if err != nil {
			fmt.Println("htmlquery error", err)
		}
		nodes := htmlquery.Find(doc, "//tbody/tr/td[1]")
		for _, node := range nodes {
			proxyIp := htmlquery.InnerText(node)
			fmt.Println("proxyIp", proxyIp)
		}
	})

	// 请求出错时， 打印错误原因
	c.OnError(func(r *colly.Response, e error) {
		fmt.Println("error", e.Error())
	})

	// 设置线程数
	c.Limit(&colly.LimitRule{
		Parallelism: 2,
	})

	//
	c.OnScraped(func(r *colly.Response) {
		fmt.Println("Finished", r.Request.URL)
	})

	// 获取前三页的地址
	for i := 2; i <= 3; i++ {
		// c.Visit("https://www.xicidaili.com/nn/" + strconv.Itoa(i))
		c.Visit("http://www.xiladaili.com/gaoni/" + strconv.Itoa(i))
	}
}

/*
curl 利用URL语法在命令行夏工作的文件传输工具
*/
